/*
 * Foogl (Friendly Object Oriented Game Library)
 * Copyright (c) 2008 Wachirawut Thamviset.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package kku.cs.fgl;

import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Vector;

import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;

public class ActorGroup implements Comparator {
	private Vector list = new Vector();

	private Vector listener = new Vector();

	private ViewPort viewPort = null;

	private int id;

	protected AbstractScene scene;

	public ActorGroup(int id) {
		this.id = id;
	}

	public void add(Actor a) {
		if (!list.contains(a)) {
			list.add(a);
			sort();
			ActorGroupListener l;
			for (int i = 0; i < listener.size(); i++) {
				l = (ActorGroupListener) listener.get(i);
				l.actorAdded(a);
			}
			a.scene = scene;
			a.input = scene.gamePane.getContainer().getInput();
			a.afterAdded();
		}
	}

	public void addActorListListener(ActorGroupListener l) {
		if (!listener.contains(l))
			listener.add(l);
	}

	public void clear() {
		list.clear();
	}

	public int count() {
		return list.size();
	}

	public Actor get(int index) {
		return (Actor) list.get(index);
	}

	public Actor get(String name) {
		Actor v[] = toArray();
		for (int i = 0; i < v.length; i++) {
			if (name.equalsIgnoreCase(v[i].getName())) {
				return v[i];
			}
		}
		return null;
	}

	public int getId() {
		return id;
	}

	public ViewPort getViewPort() {
		return viewPort;
	}

	private int oldmx, oldmy;

	private long oldTime, dTime;

	public void processInput(Input input) {
		boolean b0 = input.isMouseButtonDown(0);
		boolean b1 = input.isMouseButtonDown(1);
		boolean b2 = input.isMouseButtonDown(2);
		int mbutton = -1;
		if (b0)
			mbutton = 0;
		else if (b1)
			mbutton = 1;
		else if (b2)
			mbutton = 2;
		
		if(mbutton>=0){
			dTime = System.currentTimeMillis()-oldTime;
			oldTime = System.currentTimeMillis();
			if(dTime<60)mbutton=-1;
		}

		int mx = input.getMouseX();
		int my = input.getMouseY();
		if (oldmx == mx && oldmy == my && !(b0 || b1 || b2)) {
			oldmx = mx;
			oldmy = my;
			return;
		}
		oldmx = mx;
		oldmy = my;
		ViewPort v = null;
		if (viewPort == null)
			v = scene.getDefView();
		else
			v = viewPort;
		if (v != null) {
			mx = (int) v.toViewPortX(mx);
			my = (int) v.toViewPortY(my);
		}
		Actor all[] = toArray();
		for (int i = 0; i < all.length; i++) {
			all[i].input = input;
			all[i].setMouseXY(mx - all[i].getX(), my - all[i].getY());
			if (all[i].isVisible()) {
				if (all[i].contains(mx, my)) {
					all[i].setMouseEnterState(true);
					if (mbutton >= 0) {
						all[i].mouseClicked(mbutton);
					}
				} else {
					all[i].setMouseEnterState(false);
				}
				
			}
		}
	}

	public void remove(Actor a) {
		list.remove(a);
		ActorGroupListener l;
		for (int i = 0; i < listener.size(); i++) {
			l = (ActorGroupListener) listener.get(i);
			l.actorRemoved(a);
		}
	}

	public void removeActorListListener(ActorGroupListener l) {
		listener.remove(l);
	}

	public void removeDead() {
		Iterator it = list.iterator();
		while (it.hasNext()) {
			Actor a = ((Actor) it.next());
			a.scene = scene;
			if (a.isDead())
				it.remove();
		}
	}

	/*
	 * public void render(Graphics g) { if(viewPort==null){ Actor all[] =
	 * toArray(); for (int i = 0; i < all.length; i++) { if (all[i].isVisible())
	 * all[i].render(g); } }else{ viewPort.render(this,g); g.clearClip();
	 * g.resetTransform(); } }
	 */
	public void setViewPort(ViewPort viewPort) {
		this.viewPort = viewPort;
	}

	public void sort() {
		sort(this);
	}

	public void sort(Comparator c) {
		Collections.sort(this.list, c);
	}

	public Actor[] toArray() {
		Actor a[] = new Actor[list.size()];
		list.toArray(a);
		return a;
	}

	public void update(int delta) {
		Actor all[] = toArray();
		for (int i = all.length - 1; i >= 0; i--) {
			if (!all[i].isDead())
				all[i].update(delta);
		}
	}

	public int compare(Object a, Object b) {
		int n1 = 0, n2 = 0;
		if (a instanceof ActorGroup)
			n1 = ((ActorGroup) a).id;
		else if (a instanceof Actor)
			n1 = ((Actor) a).getZorder();

		if (b instanceof ActorGroup)
			n2 = ((ActorGroup) b).id;
		else if (b instanceof Actor)
			n2 = ((Actor) b).getZorder();
		return n1 - n2;
	}

	boolean actorChange = false;

	public void actorAdded(Actor a) {
		actorChange = true;
	}

	public void actorRemoved(Actor a) {
		actorChange = true;
	}

}
